﻿#ifndef XQHTTPSERVER_H
#define XQHTTPSERVER_H
#include<QDateTime>
#include<QHostAddress>
#include<QReadWriteLock>
#include<atomic>
#include"XQHttpObject.h"
#include"XQHttpHeadRequest.h"
#define XQHttpServerLog XQLog("XQHttpServer") //http服务器日志
class QTimer;
class XQHttpServer:public XQHttpObject
{
	Q_OBJECT
public:
	XQHttpServer(QObject*parent=nullptr);
	~XQHttpServer();
	//超时连接时间(客户端)
	int timeoutConnection()const;
	//获取服务器ip
	QString ip()const;
	//获取服务器端口
	quint16 port()const;
	//获取QTcpServer
	XQSslServer* tcp()const;
	//获取本地模式时的名字
	QString serverName_local()const;
	//获取QLocalServer
	QLocalServer* localServer()const;
	//获取内置的线程池
	XQTaskPool* taskPool()const;
	//获取客户端套接字列表
	QList<QIODevice*> clients();
public:
	//设置模式
	void setModel(NetworkType type);
	//设置运行
	bool run(NetworkType type);
	bool run();
	//关闭服务器
	void close();
	//设置端口
	void setPort(uint16_t port);
	//设置本地模式名字
	void setServerName_local(const QString& name);
	//设置超时连接时间(客户端)
	void setTimeoutConnection(int msec);
	//设置线程池运行
	void setThreadPool_run(bool run);
	//添加回复函数 业务
	void addReplyFunc(const QString& name, std::function<XQHttpHeadReply(QIODevice* socket, XQHttpHeadRequest* header, const QByteArray& data)>func);
	//删除回复函数 业务
	void removeReplyFunc(const QString& name);
	//清空回复函数 业务
	void clearReplyFunc();
	//发送信号(向客户端发送响应头)
	void sendSignals(const QString& name, const QVariantList& list);
signals://信号
	//连接上客户端
	void connected(QIODevice* socket);
	//断开与客户端连接
	void disconnected(QIODevice* socket);
protected:
	void init();
	//发送前初始化添加一些参数
	void init_headReply(XQHttpHeadReply& reply);
	//检查连接超时(客户端)
	void checkTimeoutConnection();
	//运行定时器
	void runTimeoutConnectionTimer();
protected:
	//有新的客户端链接到来
	void readyConnection();
	//断开与客户端连接
	void readyDisconnect(QIODevice* socket);
	//可以读取内容
	void readyRead(QIODevice* socket);
	//处理请求
	void handlingRequests(QIODevice* socket,XQHttpHeadRequest* header, const QByteArray& data);
	//向客户端发送数据
	void send(QIODevice* socket,const QByteArray& data);
protected:
	static XQLog* m_log;//日志服务
	QLocalServer* m_localServer = nullptr;
	QString m_localServerName="localServer";//本地方式时的名字
	XQSslServer* m_tcpServer = nullptr;
	quint16 m_port = 6666;//服务器端口
	QHostAddress m_address= QHostAddress::Any;//服务器host
	QReadWriteLock m_lock;
	struct HttpClient
	{
		QReadWriteLock lock;//读写锁
		QByteArray buff;//缓存
		QDateTime time;//最后时间
		bool accept = false;//接收完毕
		XQHttpHeadRequest head;//请求头
	};
	QHash<QIODevice*, HttpClient*> m_client;//客户端
	int m_timeout =0;//超时时间
	QTimer* m_timeoutTimer = nullptr;//检测超时的定时器
	QHash<QString, std::function<XQHttpHeadReply(QIODevice* socket, XQHttpHeadRequest* header, const QByteArray& data)>> m_replyFunc;
	bool m_thread_run = false;//是否线程池运行
	XQTaskPool* m_task=nullptr;//线程池
};
#endif // !XQHttpServer_H
